using Digitalmes.Domain.Entities.Mes.Processes;

namespace Digitalmes.Application.Mes.Processes.StepTasks.Commands;

/// <summary>
/// 复制工步命令。
/// </summary>
/// <param name="StepTaskId">要复制的工步 Id</param>
/// <param name="TaskCodePrefix">工步编号前缀</param>
/// <param name="TaskNamePrefix">工步名称前缀</param>
/// <param name="Count">数量</param>
public sealed record CopyStepTaskCommand(long StepTaskId, string TaskCodePrefix, string TaskNamePrefix, int Count) : IRequest<IResult<bool>>;

internal sealed class CopyStepTaskCommandHandler(IRepository<ProcStepTask> repo) : IRequestHandler<CopyStepTaskCommand, IResult<bool>>
{
    const int GroupSpan = 1000; // 分组区间

    public async Task<IResult<bool>> Handle(CopyStepTaskCommand request, CancellationToken cancellationToken)
    {
        // 复制工步，包括工艺标准
        // 工艺参数完整复制
        // 工步按前缀复制和当前分组区间复制

        var stepTask = await repo.AsQueryable()
             .Includes(m => m.Standards)
             .GetByIdAsync(request.StepTaskId, cancellationToken);
        if (stepTask == null)
        {
            return Result.From(true);
        }

        // 复制工艺标准前先重置部分工艺标准参数
        stepTask.Standards.ForEach(s =>
        {
            s.Id = 0;
        });

        // 找到当前分组区间的最大值
        var maxSpan = (stepTask.Seq / GroupSpan) * GroupSpan + GroupSpan;
        var startSeq = await repo.MaxAsync(m => m.StepId == stepTask.StepId && m.Seq < maxSpan, m => m.Seq, cancellationToken);
        var endSeq = startSeq + request.Count;
        if (startSeq / GroupSpan != endSeq / GroupSpan)
        {
            return Result.From(false, "工步超过分组区间");
        }

        List<ProcStepTask> stepTasks = [];
        for (var i = startSeq + 1; i <= endSeq; i++)
        {
            ProcStepTask stepTask0 = new()
            {
                StepId = stepTask.StepId,
                TaskCode = $"{request.TaskCodePrefix}{i}",
                TaskName = $"{request.TaskNamePrefix}{i}",
                Seq = i,
                WorkInstruction = stepTask.WorkInstruction,
                StandardTime = stepTask.StandardTime,
                IsCheckStandard = stepTask.IsCheckStandard,
                Standards = stepTask.Standards
            };
            stepTasks.Add(stepTask0);
        }

        if (stepTasks.Count > 0)
        {
            // 导航插入
            await repo.Context
                .InsertNav(stepTasks)
                .Include(m => m.Standards)
                .ExecuteCommandAsync();
        }

        return Result.From(true);
    }
}
